from flask import Blueprint, render_template, request, redirect, url_for, abort
from webapp.models import Pic, Album, BaseAlbum, Tag, Volume, Actress, Setting
from webapp.plugins.functions import search_, pic_page, pic_source
from flask_login import login_required
from sqlalchemy.sql import desc, func
from urllib.parse import urlsplit


pic_blueprint = Blueprint(
    'pic',
    __name__
)


@pic_blueprint.route('/')
@login_required
def home():
    if request.args.get('query_page'):
        page = pic_page(request.args.get('query_page', type=int), 'home')
    else:
        try:
            page = request.args.get('page', 0, type=int)
        except ValueError:
            page = 0
    return render_template('album.html',
                           page=page,
                           album={'label': 'home', 'id': 0, 'fake': True, 'meta': {}, 'amount': '99999+'},
                           )


@pic_blueprint.route('/albums')
@login_required
def albums():
    try:
        page = request.args.get('page', 1, type=int)
    except ValueError:
        page = 1
    per_page_pics = request.args.get('limit', type=int, default=Setting.get('per_page_pics'))
    load_all = 1 if request.args.get('all') else 0
    is_archived = request.args.get('is_archived')
    paginator = Album.paginator(page, per_page_pics, load_all=load_all, is_archived=is_archived)
    return render_template('albums.html',
                           title='Albums',
                           albums=paginator.items,
                           count=paginator.total,
                           page=page,
                           load_all=load_all,
                           )


@pic_blueprint.route('/album/<int:uid>')
@login_required
def one_album(uid):
    if not uid:
        return redirect(url_for('pic.albums'))

    if request.args.get('query_page'):
        page = pic_page(request.args.get('query_page', type=int), 'album', uid)
    else:
        try:
            page = request.args.get('page', 0, type=int)
        except ValueError:
            page = 0

    album = Album.query.get_or_404(uid)
    if not request.args.get('debug'):
        album.pv_add()
    return render_template('album.html',
                           album=album,
                           page=page,
                           )


@pic_blueprint.route('/base_album/<int:uid>')
@login_required
def one_base_album(uid):
    if not uid:
        return redirect(url_for('pic.albums'))

    if request.args.get('query_page'):
        page = pic_page(request.args.get('query_page', type=int), 'album', uid)
    else:
        try:
            page = request.args.get('page', 1, type=int)
        except ValueError:
            page = 1

    base_album = BaseAlbum.query.get_or_404(uid)
    album_list = base_album.albums.order_by(desc('id')).all()

    return render_template('albums.html',
                           albums=album_list,
                           count=len(album_list),
                           page=page)


@pic_blueprint.route('/tags')
@login_required
def tags():
    try:
        page = request.args.get('page', 1, type=int)
    except ValueError:
        page = 1
    per_page_pics = request.args.get('limit', type=int, default=Setting.get('per_page_pics'))
    load_all = 1 if request.args.get('all') else 0
    is_archived = request.args.get('is_archived')
    paginator = Tag.paginator(page, per_page_pics=per_page_pics, load_all=load_all, is_archived=is_archived)
    return render_template('albums.html',
                           title='Tags',
                           albums=paginator.items,
                           count=paginator.total,
                           page=page,
                           load_all=load_all,
                           )


@pic_blueprint.route('/tag/<int:uid>')
@login_required
def one_tag(uid):
    if request.args.get('query_page'):
        page = pic_page(request.args.get('query_page', type=int), 'tag', uid)
    else:
        try:
            page = request.args.get('page', 0, type=int)
        except ValueError:
            page = 0

    tag = Tag.query.get_or_404(uid)
    if not request.args.get('debug'):
        tag.pv_add()
    return render_template('album.html',
                           album=tag,
                           page=page,
                           )


@pic_blueprint.route('/volumes')
@login_required
def volumes():
    actress_id = request.args.get('id', '')
    try:
        page = request.args.get('page', 1, type=int)
    except ValueError:
        page = 1
    per_page_pics = request.args.get('limit', type=int, default=Setting.get('per_page_pics'))
    load_all = 1 if request.args.get('all') else 0
    is_archived = request.args.get('is_archived')
    if actress_id:
        actress = Actress.query.get_or_404(actress_id)
        paginator = Volume.paginator(
            page,
            per_page_pics=per_page_pics,
            filter_by_options={'actress_id': actress_id},
            load_all=load_all,
            is_archived=is_archived,
        )
        title = f'{actress.name}:Volumes'
    else:
        paginator = Volume.paginator(page, per_page_pics=per_page_pics, load_all=load_all, is_archived=is_archived)
        title = 'Volumes'
    return render_template('albums.html',
                           title=title,
                           albums=paginator.items,
                           count=paginator.total,
                           page=page,
                           album_id=actress_id,
                           load_all=load_all,
                           )


@pic_blueprint.route('/volume/<uid>')
@login_required
def one_volume(uid):
    try:
        page = request.args.get('page', 0, type=int)
    except ValueError:
        page = 0

    volume = Volume.query.get_or_404(uid)

    if not request.args.get('debug'):
        volume.pv_add()

    return render_template(
        'album.html',
        album=volume,
        page=page,
    )


@pic_blueprint.route('/actresses')
@login_required
def actresses():
    try:
        page = request.args.get('page', 1, type=int)
    except ValueError:
        page = 1
    per_page_pics = request.args.get('limit', type=int, default=Setting.get('per_page_pics'))
    load_all = 1 if request.args.get('all') else 0
    is_archived = request.args.get('is_archived')
    paginator = Actress.paginator(page, per_page_pics=per_page_pics, load_all=load_all, is_archived=is_archived)
    return render_template('albums.html',
                           title='Actresses',
                           albums=paginator.items,
                           count=paginator.total,
                           page=page,
                           load_all=load_all,
                           )


@pic_blueprint.route('/actress/<uid>')
@login_required
def one_actress(uid):
    try:
        page = request.args.get('page', 0, type=int)
    except ValueError:
        page = 0

    actress = Actress.query.get_or_404(uid)
    if not request.args.get('debug'):
        actress.pv_add()
    volume_list = actress.volumes.order_by(desc('id')).all()
    return render_template('album.html',
                           album=actress,
                           page=page,
                           volumes=volume_list,
                           volume_count=len(volume_list),
                           )


@pic_blueprint.route('/p/<uid>')
@login_required
def one_pic(uid):
    pic = Pic.query.get_or_404(uid)
    if not pic.delete_time and not request.args.get('debug'):
        pic.pv_add()
    url_raw = urlsplit(request.url)
    url_query = url_raw.query
    source = request.args.get('source')
    source_id = request.args.get('source_id', 0, type=int)
    source_dict = pic_source(source, source_id)

    return render_template('picture.html',
                           title=pic.note,
                           pic=pic,
                           url_query=url_query,
                           source_dict=source_dict,
                           )


@pic_blueprint.route('/archive')
@login_required
def archive():
    hottest_pics = Pic.query.order_by(desc(Pic.pv)).limit(Setting.get('archive_page_pics'))  # pv最高的图片
    highest_rate_pics = Pic.query.filter(Pic.rate == 5).order_by(func.random()).limit(Setting.get('archive_page_pics'))  # 打分最高的图片
    return render_template('archive.html',
                           title='Archive',
                           source='archive',
                           hottest_pics=hottest_pics,
                           highest_rate_pics=highest_rate_pics)


@pic_blueprint.route('/search')
@login_required
def search():
    keyword = request.args.get('key')
    result = ''
    count = None
    if keyword:
        result = search_(keyword)
        count = len(result)
    return render_template('search.html',
                           album={'label': 'search', 'id': 0, 'fake': True, 'amount': count},
                           result=result[:Setting.get('per_page_pics')],
                           )


@pic_blueprint.route('/explore')
@login_required
def explore():
    per_page_pics = request.args.get('limit', type=int, default=Setting.get('per_page_pics'))
    return render_template('album.html',
                           album={'fake': True, 'label': 'explore', 'amount': per_page_pics, 'id': 0},
                           )


@pic_blueprint.route('/compare/<src_uid>/<dst_uid>')
@login_required
def compare(src_uid, dst_uid):
    src_pic = Pic.query.filter_by(id=src_uid, delete_time=None).first()
    dst_pic = Pic.query.filter_by(id=dst_uid, delete_time=None).first()
    if not all([src_pic, dst_pic]):
        abort(404)
    return render_template('compare.html',
                           title='Compare',
                           src_pic=src_pic,
                           dst_pic=dst_pic,
                           )


@pic_blueprint.route('/slide')
@login_required
def slide():
    source = request.args.get('source')
    source_id = request.args.get('source_id')

    if source in ('album', 'tag', 'volume'):
        source_obj = eval(source.title)
        pics = source_obj.query.filter_by(id=source_id).all()